package br.com.winesys.geta.dialog;

import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;
import br.com.winesys.geta.base.ExceptionMessage;
import br.com.winesys.geta.editor.Editor;

public abstract class PropertiesActionDialog {

	protected JDialog dialog;
	private JPanel containerPanel;
	protected Editor<?> objectEditor;
	private JPanel buttonsPanel;
	private JButton okButton;
	private JButton cancelButton;

	public PropertiesActionDialog(Window parent, String title) {
		this.dialog = new JDialog(parent, title);
		this.dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
		this.dialog.setModal(true);
		this.dialog.setResizable(false);

		this.containerPanel = new JPanel();
		this.buttonsPanel = new JPanel();
		this.okButton = new JButton();
		this.cancelButton = new JButton();

		this.containerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
		this.containerPanel.setLayout(new BorderLayout());
		this.dialog.getContentPane().add(this.containerPanel, BorderLayout.NORTH);

		this.buttonsPanel.setPreferredSize(new Dimension(0, 50));

		this.okButton.setText("OK");
		this.okButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent evt) {
				PropertiesActionDialog.this.doOk();
			}
		});

		this.cancelButton.setText("Cancelar");
		this.cancelButton.addActionListener(new java.awt.event.ActionListener() {

			@Override
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				PropertiesActionDialog.this.doCancel();
			}
		});

		javax.swing.GroupLayout buttonsPanelLayout = new javax.swing.GroupLayout(this.buttonsPanel);
		this.buttonsPanel.setLayout(buttonsPanelLayout);
		buttonsPanelLayout.setHorizontalGroup(buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(buttonsPanelLayout.createSequentialGroup().addContainerGap(401, Short.MAX_VALUE).addComponent(this.okButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED).addComponent(this.cancelButton).addContainerGap()));

		buttonsPanelLayout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] { this.cancelButton, this.okButton });

		buttonsPanelLayout.setVerticalGroup(buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(buttonsPanelLayout.createSequentialGroup().addContainerGap().addGroup(buttonsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE).addComponent(this.cancelButton).addComponent(this.okButton)).addContainerGap(16, Short.MAX_VALUE)));

		this.dialog.getContentPane().add(this.buttonsPanel, java.awt.BorderLayout.SOUTH);
		this.objectEditor = createObjectEditor();
		this.containerPanel.add(this.objectEditor.getComponent(), BorderLayout.CENTER);
		this.dialog.doLayout();
		this.dialog.pack();
		this.dialog.getRootPane().setDefaultButton(this.okButton);
		this.dialog.getRootPane().registerKeyboardAction(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				doCancel();
			}
		}, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);

		Point center = GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint();
		this.dialog.setLocation((int) center.getX() - (this.dialog.getWidth() / 2), (int) center.getY() - (this.dialog.getHeight() / 2));
	}

	protected void doOk() {
		if (this.objectEditor.validate()) {
			this.dialog.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
			boolean result = false;
			try {
				Map<String, Object> params = PropertiesActionDialog.this.objectEditor.getProperties();
				result = this.execute(params);
			} catch (Exception ex) {
				this.dialog.setCursor(Cursor.getDefaultCursor());
				result = false;
				this.showException(ex);
			} 
			this.dialog.setCursor(Cursor.getDefaultCursor());	
			if (result) {
				this.dialog.setVisible(false);
			}
		}
	}

	protected void doCancel() {
		this.dialog.setVisible(false);
	}

	public void run(Map<String, Object> properties) {
		this.objectEditor.setProperties(properties);
		this.dialog.setVisible(true);
	}

	public void run() {
		this.run(new HashMap<String, Object>());
	}
	
	protected JDialog getDialog(){
		return this.dialog;
	}

	protected void showMessage(String message, String title){
		JOptionPane.showMessageDialog(this.dialog, message, title, JOptionPane.INFORMATION_MESSAGE);
	}

	protected void showException(Exception ex){
		ExceptionMessage.showMessage(this.dialog, ex);
	}

	protected void showException(String message, Exception ex){
		ExceptionMessage.showMessage(this.dialog, message, ex);
	}

	protected abstract Editor<?> createObjectEditor();
	
	protected abstract boolean execute(Map<String, Object> params);
}